<!doctype html>
<html lang="{{ site.language }}">
<!--
{% macro navLink(nav) %}
    {% if nav.uri.startsWith('/') %}
        {% set tmpPrefix = site.rootPath %}
    {% else %}
        {% set tmpPrefix = '' %}
    {% endif %}
    <a href="{{ tmpPrefix }}{{ nav.uri }}"
        {% if nav.external %} target="_blank" {% endif %}
    >{{ nav.title }}</a>
{% endmacro %}
-->

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="{{ site.description }}" />
    <meta name="keywords" content="{{ site.keywords }}" />
    <!-- request path: {{ __uri__ }} -->
    <title>{% block title %} title {% endblock %}</title>

    {% include "__analytics__.html" %}

    <script>
        // global status:
        window.gs_status = {
        };
    </script>

    <link rel="stylesheet" href="{{ site.rootPath }}/static/highlight.css">
    <link rel="stylesheet" href="{{ site.cdnPath }}/katex@0.16.9/dist/katex.min.css">
    <style>
        @font-face {
            font-family: "JetBrainsMono";
            src: url("{{ site.cdnPath }}/jetbrains-mono@1.0.6/fonts/webfonts/JetBrainsMono-Regular.woff2");
        }
        .pdf-only {
            display: none;
        }
    </style>

    {% if __mode__ == 'build' %}
    <!-- css generated by post-build.mjs -->
    <link rel="stylesheet" href="{{ site.rootPath }}/static/default-tailwind.css">
    {% else %}
    <!-- for development only -->
    <script src="https://cdn.tailwindcss.com/3.3.5?plugins=forms,typography,aspect-ratio"></script>
    <script>
        tailwind.config = {
            darkMode: 'class'
        }
        // {% if __pdf__ %}
        window.__pdf__ = true;
        // {% else %}
        window.__pdf__ = false;
        // {% endif %}
    </script>
    <style type="text/tailwindcss">
        {% include "default-tailwind.tcss" %}
    </style>
    <!--// development only -->
    {% endif %}

    <link rel="stylesheet" href="{{ site.rootPath }}/static/custom.css">

    <script>
        window.gitsite = {
            isDarkMode: function () {
                if (window.__pdf__) {
                    return false;
                }
                let colorScheme = localStorage.getItem('color-scheme');
                if (colorScheme !== null) {
                    return colorScheme === 'dark';
                }
                // detect system dark mode:
                return window.matchMedia !== undefined && window.matchMedia('(prefers-color-scheme: dark)').matches;
            },

            setDarkMode: function (isDark) {
                console.log(`set color scheme: ${isDark ? 'dark' : 'light'}`);
                localStorage.setItem('color-scheme', isDark ? 'dark' : 'light');
                if (isDark) {
                    document.documentElement.classList.add('dark');
                    document.documentElement.classList.remove('light');
                } else {
                    document.documentElement.classList.add('light');
                    document.documentElement.classList.remove('dark');
                }
            },

            encodeHtml: function (s) {
                return s.replaceAll(/\&/g, '&amp;').replaceAll(/\</g, '&lt;').replaceAll(/\>/g, '&gt;');
            },

            // load script only once:
            loadScript: function (url, onloaded, isAsync) {
                if (window._loaded_js_ === undefined) {
                    window._loaded_js_ = {};
                }
                if (!window._loaded_js_[url]) {
                    console.log(`load script: ${url}`);
                    let e = document.createElement('script');
                    e.src = url;
                    e.type = 'text/javascript';
                    if (onloaded) {
                        e.addEventListener('load', onloaded);
                    }
                    if (isAsync) {
                        e.async = true;
                    }
                    document.getElementsByTagName('head')[0].appendChild(e);
                    window._loaded_js_[url] = true;
                } else {
                    // script already loaded:
                    onloaded && onloaded();
                }
            },

            addContentChangedListener: function (callback) {
                if (window.gitsite._contentChangedListeners === undefined) {
                    window.gitsite._contentChangedListeners = [];
                }
                window.gitsite._contentChangedListeners.push(callback);
            },

            triggerContentChangedListener: function () {
                if (window.gitsite._contentChangedListeners) {
                    for (let listener of window.gitsite._contentChangedListeners) {
                        try {
                            listener();
                        } catch (err) {
                            console.error(`error when trigger content changed listener: ${listener}`);
                        }
                    }
                }
            },

            setInnerHTML: function (dom, html) {
                dom.innerHTML = html;
                Array.from(dom.querySelectorAll('script'))
                    .forEach(oldScriptEl => {
                        const newScriptEl = document.createElement('script');
                        Array.from(oldScriptEl.attributes).forEach(attr => {
                            newScriptEl.setAttribute(attr.name, attr.value);
                        });
                        const scriptText = document.createTextNode(oldScriptEl.innerHTML);
                        newScriptEl.appendChild(scriptText);
                        oldScriptEl.parentNode.replaceChild(newScriptEl, oldScriptEl);
                    });
            },

            getOuterWidth: function (dom) {
                const s = window.getComputedStyle(dom);
                const t = parseFloat(s.width) + parseFloat(s.marginLeft) + parseFloat(s.marginRight);
                return isNaN(t) ? 0 : Math.ceil(t);
            },

            showSearch: function () {
                document.getElementById('gsi-search').classList.remove('hidden');
                document.getElementById('gsi-search-input').focus();
            },

            hideSearch: function () {
                document.getElementById('gsi-search').classList.add('hidden');
            },

            showOffcanvas: function () {
                document.getElementById('gsi-offcanvas').classList.remove('hidden');
                let indexDom = document.getElementById('gsi-index');
                document.getElementById('gsi-offcanvas-index').prepend(indexDom);
                window.gs_status.show_offcanvas = true;
                const popup = document.getElementById('gsi-offcanvas-popup');
                if (popup.animate) {
                    popup.animate([{ left: "0px" }], 200).onfinish = () => popup.classList.add('gsc-offcanvas-popup-show');
                } else {
                    // animation not supported:
                    popup.classList.add('gsc-offcanvas-popup-show');
                }
            },

            hideOffcanvas: function () {
                document.getElementById('gsi-offcanvas').classList.add('hidden');
                document.getElementById('gsi-offcanvas-popup').classList.remove('gsc-offcanvas-popup-show');
                let indexDom = document.getElementById('gsi-index');
                document.getElementById('gsi-sidebar').prepend(indexDom);
                window.gs_status.show_offcanvas = false;
            },

            initPopupMenu: function (dom) {
                const popup = dom.nextElementSibling;
                if (popup && popup.classList.contains('gsc-popup-menu-container')) {
                    console.log('init popup menu: ' + dom);
                    popup.tabIndex = 0;
                    dom.addEventListener('mouseenter', function () {
                        popup.classList.remove('hidden');
                        popup.__focus = false;
                    });
                    dom.addEventListener('mouseleave', function () {
                        setTimeout(function () {
                            if (!popup.__focus) {
                                popup.classList.add('hidden');
                            }
                        }, 250);
                    });
                    dom.addEventListener('click', (e) => {
                        if (popup.__focus) {
                            popup.classList.add('hidden');
                            popup.__focus = false;
                        } else {
                            popup.classList.remove('hidden');
                            popup.__focus = true;
                            popup.focus();
                        }
                    });
                    popup.addEventListener('mouseenter', (e) => {
                        popup.__focus = true;
                    });
                    popup.addEventListener('mouseleave', (e) => {
                        popup.classList.add('hidden');
                        popup.__focus = false;
                    });
                    popup.addEventListener('focusout', (e) => {
                        popup.classList.add('hidden');
                        popup.__focus = false;
                    })
                } else {
                    console.warn('cannot init popup menu: ' + dom);
                }
            }
        };

        // set dark mode immediately:
        (function () {
            gitsite.setDarkMode(gitsite.isDarkMode());
        })();

        // equivalent of $(document).ready(fn):
        function documentReady(fn) {
            if (document.readyState === 'complete' || document.readyState === 'interactive') {
                setTimeout(fn, 0);
            } else {
                document.addEventListener('DOMContentLoaded', fn);
            }
        }

        documentReady(() => {
            console.log('auto select nav menu...');
            const gs_path_prefix = (p) => {
                if (p.endsWith('/index.html')) {
                    return p.substring(0, p.length - 10);
                }
                return p;
            }
            const urlPathPrefix = gs_path_prefix(location.href);
            document.querySelectorAll('nav.gsc-nav li.gsc-nav-li a').forEach(a => {
                if (urlPathPrefix.startsWith(gs_path_prefix(a.href))) {
                    a.classList.add('gsc-active');
                }
            });
        });

        documentReady(() => {
            console.log('init popup menu...');
            const doms = document.querySelectorAll('.gsc-popup-menu');
            for (let dom of doms) {
                gitsite.initPopupMenu(dom);
            }
        });

        documentReady(() => {
            console.log('init auto resize nav bar...');
            const resizeNavigationMenu = () => {
                if (!window.matchMedia("(min-width: 768px)").matches) {
                    return;
                }
                const
                    containerWidth = document.querySelector('#gsi-header div.gsc-container').offsetWidth,
                    menuMore = document.querySelector('#gsi-nav-menu-more'),
                    navRightWidth = document.getElementById('gsi-header-nav-right').offsetWidth;
                let info = window.__nav_resize;
                if (!info) {
                    const
                        menuItems = document.querySelectorAll('#gsi-nav-menu>li.gsc-nav-li'),
                        widthOfItems = [];
                    menuItems.forEach((dom) => {
                        widthOfItems.push(gitsite.getOuterWidth(dom));
                    });
                    info = {
                        menuItems: menuItems,
                        moreItems: document.querySelectorAll('#gsi-nav-menu-more div.gsc-popup-menu-container ul>li'),
                        widthOfLogo: gitsite.getOuterWidth(document.querySelector('#gsi-nav-menu li.gsc-nav-logo')),
                        widthOfMore: gitsite.getOuterWidth(document.querySelector('#gsi-nav-menu li#gsi-nav-menu-more')),
                        widthOfItems: widthOfItems,
                        totalWidthOfItems: widthOfItems.reduce((s, x) => s + x, 0)
                    };
                    window.__nav_resize = info;
                    console.log(`calculate resize info: ${JSON.stringify(info)}`);
                }
                console.log(`resize: container=${containerWidth}, items=${info.totalWidthOfItems}, right=${navRightWidth}`);
                // resize:
                menuMore.classList.add('invisible');
                let widthLeft = containerWidth - navRightWidth - info.widthOfLogo - info.widthOfMore - 30;
                let showMore = false;
                for (let i = 0; i < info.widthOfItems.length; i++) {
                    if (showMore) {
                        info.menuItems[i].style.display = 'none';
                        info.moreItems[i].style.display = '';
                    } else {
                        let w = info.widthOfItems[i];
                        if (widthLeft >= w) {
                            info.menuItems[i].style.display = '';
                            info.moreItems[i].style.display = 'none';
                            widthLeft -= w;
                        } else {
                            showMore = true;
                            menuMore.classList.remove('invisible');
                            info.menuItems[i].style.display = 'none';
                            info.moreItems[i].style.display = '';
                        }
                    }
                }
            };
            window.addEventListener('resize', resizeNavigationMenu);
            window.addEventListener('orientationchange', resizeNavigationMenu);
            resizeNavigationMenu();
        });
    </script>
    <script src="{{ site.cdnPath }}/abcjs@6.2.0/dist/abcjs-basic-min.js"></script>
    <script src="{{ site.rootPath }}/static/abcjs-init.js"></script>
    {% block script %}
    {% endblock %}
    <script src="{{ site.rootPath }}/static/custom.js"></script>
</head>

<body class="gsc-text gsc-bg">
    <div id="gsi-header" class="pdf-hidden gsc-bg border-b gsc-border">
        <div class="gsc-container">
            <div id="gsi-header-nav" class="relative flex items-center">
                <div id="gsi-header-nav-main" class="relative flex items-center mr-auto">
                    <nav class="gsc-nav gsc-nav-main">
                        <!-- nav for small device -->
                        <ul id="gsi-nav-menu-small" class="max-md:flex md:hidden">
                            {% if sidebar %}
                            <li class="mr-4 list-item">
                                <a href="#0" onclick="gitsite.showOffcanvas();return false;"
                                    class="block py-4 border-b-2 border-transparent">
                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
                                        stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
                                        <path stroke-linecap="round" stroke-linejoin="round"
                                            d="M8.25 6.75h12M8.25 12h12m-12 5.25h12M3.75 6.75h.007v.008H3.75V6.75zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0zM3.75 12h.007v.008H3.75V12zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0zm-.375 5.25h.007v.008H3.75v-.008zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0z" />
                                    </svg>
                                </a>
                            </li>
                            {% endif %}

                            <!-- logo -->
                            <li class="mr-4 list-item">
                                <a href="{{ site.rootPath }}/" class="inline-block py-4">
                                    <img src="{{ site.rootPath }}/static/logo.svg" class="inline-block max-w-none h-6">
                                </a>
                            </li>
                            <!--// logo -->

                            <!-- nav menu -->
                            {% if site.navigation %}
                            <li class="mr-4 list-item relative">
                                <a class="gsc-popup-menu inline-block py-4" href="#0">
                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
                                        stroke-width="1.5" stroke="currentColor" class="inline-block w-6 h-6">
                                        <path stroke-linecap="round" stroke-linejoin="round"
                                            d="M19.5 8.25l-7.5 7.5-7.5-7.5" />
                                    </svg>
                                </a>

                                <div class="gsc-popup-menu-container hidden left-0">
                                    <ul>
                                        {% for nav in site.navigation %}
                                        <li class="block">
                                            {{ navLink(nav) }}
                                        </li>
                                        {% endfor %}
                                    </ul>
                                </div>
                            </li>
                            {% endif %}
                            <!--// nav menu -->
                        </ul>
                        <!--// nav for small device -->

                        <!-- nav for desktop -->
                        <ul id="gsi-nav-menu" class="max-md:hidden md:flex">
                            <!-- logo -->
                            <li class="gsc-nav-logo mr-4 list-item">
                                <a href="{{ site.rootPath }}/" class="inline-block py-4">
                                    <img src="{{ site.rootPath }}/static/logo.svg" class="inline-block max-w-none h-6">
                                    {{ site.title }}
                                </a>
                            </li>
                            <!--// logo -->

                            <!-- nav menu -->
                            {% if site.navigation %}
                            {% for nav in site.navigation %}
                            <li class="gsc-nav-li mr-4">
                                {{ navLink(nav) }}
                            </li>
                            {% endfor %}
                            {% endif %}

                            {% if site.navigation %}
                            <li id="gsi-nav-menu-more" class="relative mr-4 invisible"><!-- more menu -->
                                <a class="gsc-popup-menu inline-block py-4" href="#0">
                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
                                        stroke-width="1.5" stroke="currentColor" class="inline-block w-6 h-6">
                                        <path stroke-linecap="round" stroke-linejoin="round"
                                            d="M19.5 8.25l-7.5 7.5-7.5-7.5" />
                                    </svg>
                                </a>
                                <div class="gsc-popup-menu-container hidden right-0">
                                    <ul>
                                        {% for nav in site.navigation %}
                                        <li class="block">
                                            {{ navLink(nav) }}
                                        </li>
                                        {% endfor %}
                                    </ul>
                                </div>
                            </li><!--// more menu -->
                            {% endif %}

                            <!--// nav menu -->
                        </ul>
                        <!--// nav for desktop -->
                    </nav>
                </div>
                <div id="gsi-header-nav-right" class="relative flex items-center">
                    <nav class="gsc-nav gsc-nav-right font-semibold">
                        <ul class="flex space-x-4">
                            <!-- search -->
                            <li><a class="inline-block py-4" href="#0" onclick="gitsite.showSearch();return false;">
                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
                                        stroke-width="1.5" stroke="currentColor" class="inline-block w-6 h-6">
                                        <path stroke-linecap="round" stroke-linejoin="round"
                                            d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z" />
                                    </svg>
                                </a>
                            </li>
                            <!--// search -->
                            <!-- light mode -->
                            <li class="gsc-hidden-on-dark">
                                <a class="inline-block py-4" href="#0"
                                    onclick="gitsite.setDarkMode(true);return false;">
                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
                                        stroke-width="1.5" stroke="currentColor" class="inline-block w-6 h-6">
                                        <path stroke-linecap="round" stroke-linejoin="round"
                                            d="M21.752 15.002A9.718 9.718 0 0118 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 003 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 009.002-5.998z" />
                                    </svg>
                                </a>
                            </li>
                            <!--// light mode -->
                            <!-- dark mode -->
                            <li class="gsc-hidden-on-light">
                                <a class="inline-block py-4" href="#0"
                                    onclick="gitsite.setDarkMode(false);return false;">
                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
                                        stroke-width="1.5" stroke="currentColor" class="inline-block w-6 h-6">
                                        <path stroke-linecap="round" stroke-linejoin="round"
                                            d="M12 3v2.25m6.364.386l-1.591 1.591M21 12h-2.25m-.386 6.364l-1.591-1.591M12 18.75V21m-4.773-4.227l-1.591 1.591M5.25 12H3m4.227-4.773L5.636 5.636M15.75 12a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0z" />
                                    </svg>
                                </a>
                            </li>
                            <!--// dark mode -->
                        </ul>
                    </nav>
                </div>
            </div>
        </div>
    </div>
    <div id="gsi-body" class="w-full">
        <div class="gsc-container">
            {% block main %}
            <p>main</p>
            {% endblock %}
        </div>
    </div>

    <div id="gsi-offcanvas" onclick="gitsite.hideOffcanvas()" class="hidden gsc-backdrop">
        <div id="gsi-offcanvas-popup" onclick="event.stopPropagation()" class="gsc-popup-container gsc-offcanvas-popup">
            <div id="gsi-offcanvas-index"></div>
        </div>
    </div>

    <div id="gsi-search" onclick="gitsite.hideSearch()"
        class="hidden gsc-backdrop z-30 fixed top-0 left-0 right-0 bottom-0">
        <div class="gsc-container">
            <div onclick="event.stopPropagation()"
                class="gsc-popup-container flex flex-col border shadow rounded-md fixed top-8 left-6 right-6 bottom-8 sd:top-12 sd:left-8 sd:right-8 sd:bottom-12 md:top-16 md:left-12 md:right-12 md:bottom-16">
                <div class="flex-none p-4 sm:p-6 md:p-8 border-b border-slate-200 dark:border-slate-700">
                    <input id="gsi-search-input" type="text" class="block w-full"
                        placeholder="Type keywords to search...">
                </div>
                <div id="gsi-search-results" class="px-4 sm:px-6 md:px-8 flex-auto overflow-y-scroll">
                    <!--
                    <div>
                        <a href="uri">title</a>
                        <p>content</p>
                    </div>
                    -->
                </div>
            </div>
        </div>
    </div>
    <script>
        window.onsearchready = (searchFn) => {
            // debug search on console:
            window.__search__ = searchFn;
            console.log('search ready.');

            function delay(callback, ms = 500) {
                let timer = 0;
                return function () {
                    let context = this, args = arguments;
                    clearTimeout(timer);
                    timer = setTimeout(function () {
                        callback.apply(context, args);
                    }, ms);
                };
            }

            function escapeHtml(unsafe) {
                return unsafe.replaceAll('&', '&amp;')
                    .replaceAll('<', '&lt;')
                    .replaceAll('>', '&gt;');
            }

            let input = document.getElementById('gsi-search-input');
            let results = document.getElementById('gsi-search-results');
            input.addEventListener('input', delay(function (e) {
                let q = e.target.value.trim();
                console.log(`start search: ${q}`);
                if (q) {
                    let rs = searchFn(q);
                    console.log(rs.length + ' found.');
                    results.innerHTML = rs.map(r => {
                        return `<div><a href="{{ site.rootPath }}${r.uri}">${escapeHtml(r.title)}</a><p>${escapeHtml(r.content)}</p></div>`;
                    }).join('\n');
                } else {
                    results.innerHTML = '';
                }
            }, 500));
        };
    </script>
    <script src="{{ site.cdnPath }}/flexsearch@0.7.31/dist/flexsearch.bundle.js"></script>
    <script src="{{ site.rootPath }}/static/search-index.js" defer></script>
</body>

</html>